package org.bjtu.word2vec.gui;

import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.io.File;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import org.deeplearning4j.api.storage.StatsStorage;
import org.deeplearning4j.ui.api.UIServer;
import org.deeplearning4j.ui.storage.InMemoryStatsStorage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.edu.bjtu.interfaces.vector.IDocumentVector;
import cn.edu.bjtu.model.dl4jword2vec.DL4jWordVecModel;


public class MainUI extends JFrame{
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	private JPanel mainJP = null;
	private GridBagLayout gl = null;
	//模型
	private DL4jWordVecModel model = null;
	//控件
	private JTextArea area;   //  最近词显示 
	private JButton loadBtn;  //记载模型
	private JButton transFileBtn;   //分类
	private JButton trainButton;  //训练模型
	private JTextArea classifyArea; 
	private JButton showConfigBtn; //显示配置
	private JButton analysisFile;  //
	private JButton showModel;    //模型
	private JButton tranformtext;   //保存模型
	private JButton nearestWords;   //求最近词
	
	//状态
	private volatile boolean isTraining  = false;
	private JCheckBox openServer ;
	UIServer server = null;
	private ThreadFactory _tf = new ThreadFactory() {
		AtomicInteger at = new AtomicInteger(0);
		@Override
		public Thread newThread(Runnable r) {
			Thread  t = new Thread(r);
			t.setName("MainUI-Event-Handler-Pool-"+at.getAndIncrement());
			return t;
		}
	};
	private ExecutorService eventHandler =  Executors.newFixedThreadPool(5,_tf);
	public MainUI() {
		super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		gl  = new GridBagLayout();
		mainJP = new JPanel(gl);
		setSize(1024, 768);
		setTitle("Word2Vec测试");
		init();
		setContentPane(mainJP);
		setVisible(true);
		initEventHandler();
		showMessage("!!!点击训练模型之后,配置文件中的指向的模型保存文件将会被覆盖,一个注意保存", true);
	}
	/**
	 * 控件布局函数
	 */
	private void init(){
		//X往右,Y往下
//		layout(new JLabel("Model测试"),new GBC(0,0).setGridWidth(5).setGridHeight(1).setFill(GridBagConstraints.BOTH).setWx(1).setWy(1));
		area = new JTextArea("",30,30);
		area.setLineWrap(true);
		JScrollPane js = new JScrollPane(area);
		js.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
		js.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		layout(js,new GBC(0, 1).setFill(GridBagConstraints.BOTH).setWx(1).setWy(1).setGridHeight(10).setGridWidth(10));
		classifyArea = layout(new JTextArea("Result goes here"),new GBC(10,1).setGridHeight(10).setGridWidth(10).setFill(GridBagConstraints.BOTH).setWx(1).setWy(1));
		classifyArea.setLineWrap(true);
		
		trainButton = layout(new JButton("训练模型"),new GBC(0,14));
		loadBtn = layout(new JButton("加载模型"),new GBC(1,14));
		showModel = layout(new JButton("查看模型参数"),new GBC(2,14));
		transFileBtn = layout(new JButton("文档文件转换"),new GBC(3,14));
		tranformtext = layout(new JButton("单文档转换"),new GBC(4,14));
		nearestWords = layout(new JButton("求近似词"),new GBC(5,14));
		showConfigBtn = layout(new JButton("查看配置"),new GBC(6,14));
		analysisFile = layout(new JButton("打开文件"),new GBC(7,14));
		layout(new JLabel("训练模型时打开UIServer"),new GBC(8,14).setFill(GBC.BOTH).setAnchor(GBC.EAST));
		openServer = layout(new JCheckBox(),new GBC(9,14).setAnchor(GBC.EAST).setFill(GBC.BOTH));
	}
	private void showMessage(String msg,boolean left){
		if(left){
			area.setText(msg);
		}else{
			classifyArea.setText(msg);
		}
	
	}
	private <T extends Component> T layout(T comp,GBC gbc){
		mainJP.add(comp,gbc);
		return comp;
	}
	/**
	 * 为相应的button添加事件监听
	 */
	private void initEventHandler(){
		loadBtn.addActionListener((e)->{
			logger.info("Event");
			eventHandler.submit(()->{
				if(model == null){
					model = DL4jWordVecModel.getInstance();
				}
				JFileChooser jf = new JFileChooser(new File("E:\\LiYao\\fd\\").getParent());
				int res = jf.showOpenDialog(this);
				if(res == JFileChooser.APPROVE_OPTION){
					showMessage("加载模型中。。。。",true);
					model.loadModelFromFile(jf.getSelectedFile());
					showMessage("加载完成....",true);
				}
			});
		});
		transFileBtn.addActionListener((e)->{
			logger.info("Event");
			String text = area.getText().trim();
			if(text.length()>0){
				eventHandler.submit(()->{
					if(model == null){
						model = DL4jWordVecModel.getInstance();
					}
					if(model.getWord2Vec()==null){
						showMessage("请先加载模型....",true);
					}else{
					JFileChooser jf = new JFileChooser();
					jf.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
					int res = jf.showOpenDialog(this);
					if(res == JFileChooser.APPROVE_OPTION){
						showMessage("文档转换中。。。。",true);
						List<IDocumentVector> docVecs = null;
						try {
							docVecs = model.transform(model.getDocuments(jf.getSelectedFile().getAbsolutePath()));
						} catch (Exception e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
						StringBuilder sb = new StringBuilder();
						for(IDocumentVector docvec:docVecs){
							sb.append(docvec.getDocId()+"\t"+docvec.getDocLabel()+"\r\n");
							for(int i=0 ;i<docvec.getVector().size();i++){
								sb.append(docvec.getVector().get(i)+" ");
							}
							sb.append("\r\n");
						}		
						showMessage(sb.toString(),true);
					}
				}
				});
			}
		});
		trainButton.addActionListener((e)->{
			logger.info("Event");
			eventHandler.submit(()->{
				if(!isTraining){
					//不会有并发问题,但是防止重复训练浪费时间
					isTraining = true;
					trainButton.setEnabled(false);
					if(model == null){
						model = DL4jWordVecModel.getInstance();
					}
					if(openServer.isSelected()){
						server = UIServer.getInstance();
						StatsStorage stats = new InMemoryStatsStorage();
						server.attach(stats);
					}
					JFileChooser jf = new JFileChooser();
					jf.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
					int res = jf.showOpenDialog(this);
					if(res == JFileChooser.APPROVE_OPTION){
					model.builderModel(jf.getSelectedFile().getAbsolutePath());
					trainButton.setEnabled(true);
					isTraining = false;
					}
				}
				return model;
			});
		});
		showConfigBtn.addActionListener((e)->{
			logger.info("Event");
		//	new ConfigFrame(MainUI.this);
		});
		analysisFile.addActionListener((e)->{
			logger.info("Event");
			JFileChooser jf = new JFileChooser(new File("E:\\LiYao\\fd\\").getParent());
			int res = jf.showOpenDialog(this);
			if(res == JFileChooser.APPROVE_OPTION){
				new DataFileView(this, jf.getSelectedFile());
			}
		});
		showModel.addActionListener((e)->{
			new ShowModelJFrame(this);
		});
		
		nearestWords.addActionListener((e)->{
			logger.info("Event");
			if(model==null){
				showMessage("请先加载模型!!!!",true);
			}else{
			    new NearestWordsFrame(MainUI.this);
			}
		});
		openServer.setSelected(true);
		
		tranformtext.addActionListener((e)->{
			logger.info("Event");
			if(model==null){
				showMessage("请先加载模型!!!!",true);
			}else{
			   new DocTransform(MainUI.this);
			}
		});
	}
	
}
